## django 自带的库
from django.contrib import admin
from django.forms import Textarea

from .models import Device,DevBackups,monitor,inter,inter_count
from django.utils.html import format_html
from django.shortcuts import render,redirect,HttpResponse
from django.utils.translation import gettext_lazy


## python 自带的库
import base64
import requests
from netmiko import ConnectHandler
from datetime import datetime
import time
import os
import netmiko
from multiprocessing.pool import ThreadPool


## 第三方插件
from import_export.admin import ImportExportModelAdmin





## 配置下载按钮
def backup_download(modeladmin,request,queryset):
    for obj in queryset:
        file_name = DevBackups.objects.filter(id=obj.id).first()
        file_path = f"net_dev/command/backup/{file_name.title}"
        with open(file_path,'rb') as file:
            file_data = file.read()

        response = HttpResponse(file_data, content_type='application/octet-stream')
        response['Content-Disposition'] = 'attachment; filename="{}"'.format(os.path.basename(file_path))
        return response


backup_download.short_description = u"配置下载"

## 配置删除按钮
def delete(modeladmin,request,queryset):
    for obj in queryset:
        file_name = DevBackups.objects.filter(id=obj.id).first()
        file_path = f"net_dev/command/backup/{file_name.title}"
        os.remove(file_path)
        DevBackups.objects.filter(id=obj.id).delete()

delete.short_description = u"配置删除"

"""设备配置备份"""
class Dev_Backup(admin.ModelAdmin):


    ## 设备管理中所展示的信息
    list_display = ("title","time","ip")

    #  search_fields = ("title","time","ip")

    list_filter = ("title","time","ip")

    ## 注册按钮；将配置下载和配置删除功能注册
    actions = [backup_download,delete]

    ## 覆盖django自带的增加和删除按钮；创建好一个类后，会自动有添加和删除的按钮。进行覆盖。
    def has_add_permission(self, request):
        return False

    def has_delete_permission(self, request, obj=None):
        return False

admin.site.register(DevBackups,Dev_Backup)

#
#
# ########################################################################################
#
#


##  定义一个配置备份的界面；
def dev_backup(modeladmin,request,queryset):
    if request.method == 'POST':
        now = datetime.now()
        date = f'{now.month}_{now.day}_{now.year}'
        result = []
        def fw_session(ip,outpu):
            # 留个其他厂商或者防火墙等设备
            pass

        try:
            for obj in queryset:
                def cisco_ssh(ip, username, password,vendor):
                    cisco = {
                        "device_type": "cisco_ios",
                        "ip": ip,
                        "username": username,
                        "password": password,
                    }

                    huawei = {
                        "device_type": "huawei",
                        "ip": ip,
                        "username": username,
                        "password": password,
                    }

                    if vendor == 'cisco':
                        conn = ConnectHandler(**cisco)
                        output = conn.send_config_from_file('net_dev/command/cisco_comm.txt')
                        # output = conn.send_command('show clock')
                        with open("net_dev/command/backup/" + ip + "_" + date + ".txt", 'a') as f:
                            f.write(output)

                        data_dic = {"title": ip + "_" + date + ".txt",
                                    "time": now,
                                    "ip": ip}
                        DevBackups.objects.create(**data_dic)
                        result.append(f'{obj.ip}配置备份成功!')

                    elif vendor == 'huawei':
                        conn = ConnectHandler(**huawei)
                        output = conn.send_config_from_file('net_dev/command/cisco_comm.txt')
                        # output = conn.send_command('show clock')
                        with open("net_dev/command/backup/" + ip + "_" + date + ".txt", 'a') as f:
                            f.write(output)

                        data_dic = {"title": ip + "_" + date + ".txt",
                                    "time": now,
                                    "ip": ip}
                        DevBackups.objects.create(**data_dic)
                        result.append(f'{obj.ip}配置备份成功!')
                pool = ThreadPool(20)
                pool.apply_async(cisco_ssh, args=(obj.ip, obj.username, obj.password,obj.vendor.lower()))
                pool.close()
                pool.join()


                # if obj.vendor.lower() == 'cisco':
                #     def sk_session(ip, username, password):
                #         sw = {"device_type": "cisco_ios", "ip": ip, "username": username, "password": password}
                #         conn = ConnectHandler(**sw)
                #         # output = conn.send_config_from_file('net_dev/command/cisco_comm.txt')
                #         output = conn.send_command('show clock')
                #         with open("net_dev/command/backup/" + ip + "_" + date + ".txt",'a') as f:
                #             f.write(output)
                #
                #         data_dic = {"title": ip + "_" + date + ".txt",
                #                     "time": now,
                #                     "ip": ip}
                #         DevBackups.objects.create(**data_dic)
                #
                #     sk_session(obj.ip,obj.username,obj.password)
                #     time.sleep(3)
                #     result.append(f'{obj.ip}配置备份成功!')
                #
                # elif obj.vendor.lower() == "huawei":
                #     def hw_session(ip, username, password):
                #         sw = {"device_type": "huawei", "ip": ip, "username": username, "password": password}
                #         conn = ConnectHandler(**sw)
                #         # output = conn.send_config_from_file('net_dev/command/hw_comm.txt')
                #         output = conn.send_command('dis clock')
                #         with open("net_dev/command/backup/" + ip + "_" + date + ".txt", 'a') as f:
                #             f.write(output)
                #
                #         data_dic = {"title": ip + "_" + date + ".txt",
                #                     "time": now,
                #                     "ip": ip}
                #         DevBackups.objects.create(**data_dic)
                #
                #     hw_session(obj.ip, obj.username, obj.password)
                #     time.sleep(3)
                #     result.append(f'{obj.ip}配置备份成功!')
                # else:
                #     pass
        except Exception as e:
            pass

        result = '\n'.join(result)
        time.sleep(3)
        return render(request, 'backup.html', {"result": result})

## 新增按钮显示
dev_backup.short_description = u"设备配置备份"



## 设备展示
class DeviceMgmt(ImportExportModelAdmin):
    ## 设备管理中所展示的信息
    list_display = ('ip', 'dev_name', 'diqu', 'weizhi', 'jigui', 'xinghao', 'sn', 'vendor', 'leixing', "enter","设备管理")

    ## 筛选条件;admin 界面右侧多出一个过滤器
    list_filter = ('ip', 'diqu', 'xinghao', 'sn', 'vendor', 'leixing')

    # filter_horizontal = ('tags',)     # 多对多字段显示
    # list_per_page = 1                 # 每页显示几条数据
    # list_editable = ('source',)       # 可编辑的字段
    # readonly_fields = ('qq',)         # 只读字段
    # exclude = ('name',)               # 添加和修改时那些界面不显示
    # date_hierarchy = 'ctime'          # 详细时间分层筛选　
    # actions = ['test_action', ]       # 之定义的action函数
    # 排序
    # ordering = ('hr_result', 'second_result', 'first_result')
    # list_per_page = 100                 # 每页可显示的最大数据
    # List_display_links = None  # 禁用编辑链接


    ## 用来展示搜索;界面多出一个搜索框，支持一下搜索
    #  search_fields = ('ip', 'dev_name', 'diqu')

    ## 在添加设备展示信息时，进行分组展示；所在同一个组同属于同一行；如果没分组的话，一个信息占一行；使用vue主题模版，分组不显示
    fieldsets = (
        ('设备管理信息', {'fields': ("ip", "dev_name", "username","password","leixing","snmp")}),
        ('设备基础信息', {'fields': ("vendor","xinghao","diqu", "weizhi", "jigui","enter")}),)




    ## 设备管理操作
    def 设备管理(self,obj):
        if obj.leixing == "switch" or obj.leixing == "router":
            ip = obj.ip
            user = obj.username
            pwd = obj.password
            base_pwd = str(base64.urlsafe_b64encode(pwd.encode("utf-8")), "utf-8")
            return format_html(f'<a href="http://127.0.0.1:8888/?hostname={ip}&username={user}&password={base_pwd}",target="_blank">登录设备</a>')
        elif obj.leixing == "server":
            return  HttpResponse("404")
            # rdp_server_ip = obj.ip
            # rdp_server_port = 3389
            # username = 'yunhui.adm'
            # password = 'shopee!QAZ'
            # session = winrm.Session(rdp_server_ip, auth=(username, password))
            # command = 'MSTSC /v:{}:{}'.format(rdp_server_ip, rdp_server_port)
            # result = session.run_ps(command)
            # context = {
            #     'result': result.std_out.decode('utf-8'),
            #     }
            # return render(self.request, 'rdp_login.html', context)

        else:
            return " "


    ## 注册按钮
    actions = [dev_backup]
    # # Action选项都是在页面上方显示
    # actions_on_top = True
    # # Action选项都是在页面下方显示
    # actions_on_bottom = False
    # # 是否显示选择个数
    # actions_selection_counter = True




admin.site.register(Device,DeviceMgmt)


# class ConfigADmin(admin.ModelAdmin):
#
#     list_display = ("name","ip_to")
#
#
# admin.site.register(Configuration,ConfigADmin)
#



###########       设备运行状态    ########################3

class MonitorMgmt(admin.ModelAdmin):

    list_display = ["net_ip",'time',"Cpu_Speed","Mem_Speed"]

    ## 去掉django自带的增加和删除按钮
    def has_add_permission(self, request):
        return False

    def has_delete_permission(self, request, obj=None):
        return False

    list_display_links = None  # 禁用编辑链接

admin.site.register(monitor,MonitorMgmt)



class InterMgmt(admin.ModelAdmin):

    list_display = ["inters",'state',"protocol","inuti","oututi","inerros","outerros"]

    ## 定义查询条件
    list_filter = ("inters",'state',"protocol","inuti","oututi","inerros","outerros")

    ## 每页可展示的数据
    list_per_page = 25

    ## 去掉django自带的增加和删除按钮
    def has_add_permission(self, request):
        return False

    def has_delete_permission(self, request, obj=None):
        return False

    list_display_links = None  # 禁用编辑链接

admin.site.register(inter,InterMgmt)



class inters(admin.ModelAdmin):
    list_display = ["ip",'inter_count',"up","down"]

    ## 定义查询条件
    list_filter = ("ip",'inter_count',"up","down")

    ## 每页可展示的数据
    list_per_page = 20

    ## 去掉django自带的增加和删除按钮
    def has_add_permission(self, request):
        return False

    def has_delete_permission(self, request, obj=None):
        return False

    list_display_links = None  # 禁用编辑链接

admin.site.register(inter_count,inters)

